<?php
/**
 * Copyright 2008 francissem (http://www.webmoss.net)(francissem@gmail.com)
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 		http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @author francissem
 * @copyright 2008 francissem (http://www.webmoss.net)(francissem@gmail.com)
 * @license http://www.apache.org/licenses/LICENSE-2.0
 */
require_once(dirname(__FILE__)."/Module/Exception.php");
require_once(dirname(__FILE__)."/Repository/Agent/Interface.php");
class Core_Module implements Core_Repository_Agent_Interface {
		
	private $name;
	private $version;
	private $url;
	
	private $template_location;
	private $script_location;
	private $contents_location;
	
	private $resource_location;
	private $resource_layout_location;
	private $resource_script_location;
	
	private static $modules_list;
	private static $modules_pool;
	
	/**
	 * implements Repository_IRepository
	 */
	private static $repos_pool;
	static function addRepository($name,Core_Repository_Abstract $repos){
		self::$repos_pool[$name]=$repos;
	}
	static function getRepository($name){
		return self::$repos_pool[$name];	
	}
	static function getRepositories(){
		return self::$repos_pool;
	}
	
	
	static function load($modules_location){
		$repos = self::getRepository("cache");
		
		if(!isset($repos)) throw new Core_Module_Exception("Please select a repository to cache up the modules list. Use Core_System::SetRepository");
		
		$repos->selectCursor("modules_info");
		
		$g_setting  = Core_System::GetSetting("general");
		
		if(filemtime($modules_location)>$repos->getCursorLastModifiedTime() || $g_setting["mode"]=="debug"){
			$list = scandir($modules_location);
			$classes_paths=array();
			$module_infos=array();
			$url_map = array();
			foreach($list as $p){
				$module_classes_path = pathjoin($modules_location,$p,"classes");
				if(is_dir($module_classes_path))
					$classes_paths[]=$module_classes_path;
				$ini_file = pathjoin($modules_location,$p,"info.ini");
				if(is_file($ini_file)){
					$module_infos[$p] = parse_ini_file($ini_file);
					$module_infos[$p]["name"] = $p;
					$url_map[$module_infos[$p]["url"]]=$p;
				}
			}
			$info=array(
				"classes_paths"=>$classes_paths,
				"module_infos"=>$module_infos,
				"url_map"=>$url_map
			);
			//require_once("Core/Repository/Data/Array.php");
			$repos->saveDataObject(new Core_Repository_Data_New_Array($info));
		}else{
			$info = $repos->acquireDataObject()->getContent();
		}
		
		self::$modules_list=$info;
		
		
		set_include_path(get_include_path().PATH_SEPARATOR.implode(PATH_SEPARATOR,$info["classes_paths"]));
	}
	
	static function getModule($module_name){
		if(!isset(self::$modules_pool[$module_name])){
			
			if(!array_key_exists($module_name,self::$modules_list["module_infos"])) throw new Core_Module_Exception("Module {$module_name} not exists");
			self::$modules_pool[$module_name] = new Core_Module(self::$modules_list["module_infos"][$module_name]);
		}
		
		return self::$modules_pool[$module_name];
	}
	
	static function getModuleUrlMap(){
		return self::$modules_list["url_map"];
	}
	
	static function getAllModuleInfo(){
		return self::$modules_list;
	}
	
	function __construct($module_info){
		
		$this->name = $module_info["name"];
		$this->version = $module_info["version"];
		
		$this->template_location = pathjoin(__MODULES__,$this->name,isset($module_info["template_location"])?$module_info["template_location"]:"template");
		$this->script_location = pathjoin(__MODULES__,$this->name,isset($module_info["script_location"])?$module_info["script_location"]:"script");
		$this->contents_location = pathjoin(__MODULES__,$this->name,(isset($module_info["contents_location"])?$module_info["content_location"]:"contents"));
		
	}
	
	function getInfo($key=null){
		if(isset($key)) return self::$modules_list["module_infos"][$this->name][$key];
		return self::$modules_list["module_infos"][$this->name];
	}
	
	function getController(){
		$c = self::$modules_list["module_infos"][$this->name]["controller_class"];
		if(!isset($c)) return;
		
		
		//require_once($c.".php");
		return new $c();
	}
	
	function getContentsLocation(){
		return $this->contents_location;
	}
	
	function getName(){
		return $this->name;
	}
	
	function getVersion(){
		return $this->version;
	}
	
	private function getPublicResourceLocation(){
		if(!isset($this->resource_location))
			$this->resource_location=pathjoin(__ROOT__,Core_System::GetSetting("structure","clientside_resource_location"));
		return $this->resource_location;
	}
	
	
	
	function buildPublicResource(){
		static $is_builded;
		if($is_builded==true){
			return;
		}
		$this->resource_location = $this->getPublicResourceLocation();
		$this->resource_layout_location = pathjoin($this->resource_location,"template",$this->getName());
		$this->resource_script_location = pathjoin($this->resource_location,"script",$this->getName());
		
		$this->resource_template_url = pathjoin(__PUBLIC_URL__,"tempate",$this->name);
		$this->resource_script_url = pathjoin(__PUBLIC_URL__,"script",$this->name);
		
		
		
		Core_System::MakeDirectory($this->resource_layout_location);
		Core_System::MakeDirectory($this->resource_script_location);
		
		
		$repos = self::getRepository("cache");
		$repos->selectCursor($this->name);
		if($repos->readDataObject()){
			$info = $repos->readDataObject()->getContent();
		}
		if($info==NULL) $info=array("template_resource_last_modified"=>0,"script_resource_last_modified"=>0);
		
		$template_changed=false;
		$script_changed=false;
		$this->copyTemplateResource($this->template_location,$info["template_resource_last_modified"],&$template_changed);
		$this->copyScriptResource($this->script_location,$info["script_resource_last_modified"],&$script_changed);

		if($template_changed) $info["template_resource_last_modified"]=time();
		if($script_changed) $info["script_resource_last_modified"]=time();
		require_once("Core/Repository/Data/Array.php");
		$repos->saveDataObject(new Core_Repository_Data_Array($info));
		$is_builded=true;
	}
	
	private function copyTemplateResource($resource_source_location,$mtime=0,$changed){
		foreach(glob($resource_source_location."/*") as $sf){
			$df = pathjoin($this->resource_location,"template",$this->name,preg_replace("/^".str_replace('/','\/',$this->template_location)."\//","",$sf));
			
			if(is_dir($sf))	{
				Core_System::MakeDirectory($df);
				$this->copyTemplateResource($sf,$mtime,$changed);
			}
			
			if(is_file($sf) && basename($sf)!="Thumbs.db" && filemtime($sf) > $mtime) {
				if(preg_match("/.*\.(xsl|css)$/",$sf)){
					$this->relocateServerVarFile($sf,$df);
				}else{
					copy($sf,$df);
				}
				$changed=true;
			}
		}
	}
	
	private function copyScriptResource($resource_source_location,$mtime=0,$changed){
		foreach(glob($resource_source_location."/*") as $sf){
			$df = pathjoin($this->resource_location,"script",$this->name,preg_replace("/^".str_replace('/','\/',$this->script_location)."\//","",$sf));
			if(is_dir($sf))	{
				Core_System::MakeDirectory($df);
				$this->copyScriptResource($sf,$mtime,$changed);
			}
			if(is_file($sf) && basename($sf)!="Thumbs.db" && filemtime($sf) > $mtime) {
				copy($sf,$df);
				$changed=true;
			}
		}
	}

	function destroyPulicResource(){
		$dir = $this->getPublicResourceLocation();
		if(is_dir($dir)) Core_System::RemoveFile($dir);
	}
	
	
	private function relocateServerVarFile($source_file,$des_file){
		$r_url_base = pathjoin("/",Core_System::GetSetting("general","url_base"),Core_System::GetSetting("structure","clientside_resource_location"));
		$content = file_get_contents($source_file);
		$content = strtr($content,array("%%module_name%%"=>$this->name,
										"%%template_resource_location%%"=>pathjoin($r_url_base,"template",$this->name),
										"%%script_resource_location%%"=>pathjoin($r_url_base,"script",$this->name),
										));
		//%%module_url%%
		file_put_contents($des_file,$content);
	}
	
}
?>